package cn.open.feishu.alert.config;

import cn.open.feishu.alert.common.SendAsyncExecutor;
import cn.open.feishu.alert.context.FeishuHandlerContext;
import cn.open.feishu.alert.context.SpringContext;
import cn.open.feishu.alert.log.LoggerHandler;
import cn.open.feishu.alert.support.FeishuAlertClient;
import cn.open.feishu.alert.support.FeishuAlertService;
import cn.open.feishu.alert.support.FeishuAlertServiceImpl;
import cn.open.feishu.alert.support.CounterNativeCache;
import cn.open.feishu.alert.support.Handler.AtFeishuAlertHandler;
import cn.open.feishu.alert.support.Handler.DefaultFeishuAlertHandler;
import cn.open.feishu.alert.support.Handler.PrivateFeishuAlertHandler;
import cn.open.feishu.alert.support.Handler.PrivateFeishuDirectAlertHandler;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.EnableAsync;

import java.util.concurrent.TimeUnit;

/**
 * @Description 飞书机器人告警配置类
 * @Author fandy.lin
 * @Date 2021/11/23 上午9:54
 **/
@Configuration
@EnableAsync
@Import({FeishuHandlerContext.class})
public class FeiShuAlertAutoConfiguration {
    @Bean
    public FeishuAlertService feishuAlertService(FeiShuProperties properties, FeishuAlertClient client, CounterNativeCache cache, Environment env) {
        return new FeishuAlertServiceImpl(properties, cache, client, env);
    }

    @Bean
    public FeishuAlertClient feishuAlertClient(FeiShuProperties feiShuProperties) {
        return FeishuAlertClient.builder().feiShuProperties(feiShuProperties).build();
    }

    @Bean
    public CounterNativeCache counterNativeCache(FeiShuProperties feiShuProperties) {
        Cache<String, Integer> cache = CacheBuilder.newBuilder()
                .initialCapacity(feiShuProperties.getCacheInitSize())
                .maximumSize(feiShuProperties.getCacheMaxSize())
                .expireAfterWrite(feiShuProperties.getAwaitTime(), TimeUnit.SECONDS)
                .build();
        return new CounterNativeCache(feiShuProperties, cache);
    }

    @Bean
    public DefaultFeishuAlertHandler defaultFeishuAlertHandler(Environment env, FeiShuProperties feiShuProperties, ButtonProperties buttonProperties, FeishuAlertClient feishuAlertClient) {
        return new DefaultFeishuAlertHandler(env, feiShuProperties, buttonProperties, feishuAlertClient);
    }

    @Bean
    public AtFeishuAlertHandler atFeishuAlertHandler(Environment env, FeiShuProperties feiShuProperties, ButtonProperties buttonProperties, FeishuAlertClient feishuAlertClient) {
        return new AtFeishuAlertHandler(env, feiShuProperties, buttonProperties, feishuAlertClient);
    }

    @Bean
    public PrivateFeishuAlertHandler privateFeishuAlertHandler(Environment env, FeiShuProperties feiShuProperties, ButtonProperties buttonProperties, FeishuAlertClient feishuAlertClient) {
        return new PrivateFeishuAlertHandler(env, feiShuProperties, buttonProperties, feishuAlertClient);
    }

    @Bean
    public PrivateFeishuDirectAlertHandler privateFeishuDirecAlertHandler(Environment env, FeiShuProperties feiShuProperties, ButtonProperties buttonProperties, FeishuAlertClient feishuAlertClient) {
        Cache<String, String> cache = CacheBuilder.newBuilder()
                .initialCapacity(feiShuProperties.getCacheMaxSize())
                .maximumSize(feiShuProperties.getCacheMaxSize())
                .build();
        return new PrivateFeishuDirectAlertHandler(env, feiShuProperties, buttonProperties, feishuAlertClient,cache);
    }

    @Bean
    public LoggerHandler loggerHandler(FeishuAlertService feishuAlertService) {
        return new LoggerHandler(feishuAlertService);
    }

    @Bean
    public SpringContext springContext() {
        return new SpringContext();
    }

    @Bean
    public SendAsyncExecutor sendAsyncExecutor(FeiShuProperties feiShuProperties) {
        return new SendAsyncExecutor(feiShuProperties);
    }

    @Bean
    public FeiShuProperties feiShuProperties() {
        return new FeiShuProperties();
    }

    @Bean
    public ButtonProperties buttonProperties() {
        return new ButtonProperties();
    }

    @Bean
    public HttpClientProperties httpClientProperties() {
        return new HttpClientProperties();
    }
}